<?php

namespace App\Models;


use App\Service\Base\Model;
use App\Service\Translate;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\DB;

class News extends Model
{

    // 用户管理
    protected $table = 'news';
    // 是否草稿 草稿不用表单验证
    protected $is_draft = false;

    // 缓存字段，用于搜索绑定的字段
    protected $cacheFields = ['id', 'uid', 'is_top', 'verify', 'is_major', 'is_header', 'tag_id', 'cate_id', 'is_email'];

    // 是草稿
    public function is_draft($is_draft = true)
    {
        $this->is_draft = $is_draft;

        return $this;
    }

    // 添加
    //public function oneAdd($data = [])
    public function publish($uid, $data, $cates = [], $tags = [])
    {
        // 验证
        if(empty($uid)){
            //return $this->return_false('select_the_posting_user');
        }
        // 必须选择栏目
        if(empty($cates)){
            //return $this->return_false('select_the_posting_cate');
        }
        /*if(empty($data['en_content']) || empty($data['cn_content']) || empty($data['tc_content'])){
            return $this->return_false('fill_the_content');
        }*/
        if(empty($tags) && (!empty($data['en_keyword']))){
            $tags = $this->keywordToTag($data['en_keyword']);
        }

        // 参数
        $data['uid'] = $uid;
        $news_id     = $data['id'] ?? 0;
        $is_draft    = $data['is_draft'] ?? 0;

        // 如果是草稿
        if(!empty($is_draft)){
            $cates  = [];
            $tags   = [];
            $rules  = $this->fieldRule();
            $result = $this->validator($data, $rules, ['id' => 'select_operation_id']);
            if($result === false){
                return false;
            }
        }

        // 模型
        $descDb  = new NewsDesc();
        $nTagDb  = new NewsTag();
        $sTagDb  = new SiteTag();
        $nCateDb = new NewsCate();
        $sCateDb = new SiteCate();
        $userDb  = new User();

        // 发帖数量
        $numberAdd = ['number' => DB::raw('number+1'), 'mtime' => LARAVEL_TIME];
        $numberDsc = ['number' => DB::raw('number-1'), 'mtime' => LARAVEL_TIME];

        // 如果是修改 查询内容信息
        $info     = [];
        $descInfo = [];
        if($news_id){
            $info = $this->isCache(true)->oneFind(["id" => $data['id']]);
            $info = is_object($info) ? $info->toArray() : $info;
            if(empty($info)){
                return $this->return_false('data_modify_has_not_exist');
            }
            if($info['verify'] == -1){
                return $this->return_false('data_modify_has_been_deleted');
            }
            // 已经发布了的内容不能在保存为草稿
            if(empty($info['is_draft']) && $is_draft){
                return $this->return_false('published_content_cannot_saved_as_draft');
            }
            //$read_no    = $info['read_no'];
            //$virtual_no = $info['virtual_no'];

            // 以前的栏目
            $ftWhere    = ['news_id' => $news_id];
            $oldCates   = $nCateDb->isCache(true)->getList($ftWhere, 0);
            $oldCateIds = array_column($oldCates, 'cate_id');
            // 以前的标签
            $fwWhere   = ['news_id' => $news_id];
            $oldTags   = $nTagDb->isCache(true)->getList($fwWhere, 0);
            $oldTagIds = array_column($oldTags, 'tag_id');

            // 是否改变
            $addTagIds  = array_diff($tags, $oldTagIds, [0, '']); // 添加的标签
            $desTagIds  = array_diff($oldTagIds, $tags, [0, '']); // 减少的标签
            $addCateIds = array_diff($cates, $oldCateIds, [0, '']); // 添加的栏目
            $desCateIds = array_diff($oldCateIds, $cates, [0, '']); // 减少的栏目

            // 数据
            $articleData = $this->filterField($data);
            $descData    = $descDb->filterField($data);
            if($descData){
                $descInfo = $descDb->isCache(true)->oneFind(['news_id' => $news_id]);
            }
        } else{
            // 模型数据
            $articleData = $this->filterField($data);
            $descData    = $descDb->filterField($data);
            $this->fill($articleData);
            $descDb->fill($descData);

            // 是否改变
            $addTagIds  = $tags; // 添加的标签
            $desTagIds  = []; // 减少的标签
            $addCateIds = $cates; // 添加的栏目
            $desCateIds = []; // 减少的栏目
        }

        // 保存数据
        DB::beginTransaction();
        try{
            /*// 如果有置顶
            if($is_top){
                // 取消其他置顶
                $result = $this->where(['is_top' => $is_top])->update(['is_top' => 0]);
            }*/

            // 修改
            if($news_id){
                unset($data['id'], $descData['id']);
                // 主表
                if($articleData){
                    $result = $this->where('id', $news_id)->update($articleData);
                }
                // 附表
                if($descData){
                    $result = $descDb->where('news_id', $news_id)->update($descData);
                }
            } else{
                // 添加
                $this->save();
                $news_id = $this->id;
                // 详情表
                $descDb->news_id = $news_id;
                // 整理
                $result = $descDb->save();
            }

            // 完善请求链接
            $link  = atwArticleLink($data['en_title'] ?? '', $news_id);
            $info2 = $this->where('link', $link)->where('id', '!=', $news_id)->where('verify', '>=', 0)->first();
            if($info2){
                throw new \Exception('link_has_exist');
            }
            $this->where('id', $news_id)->update(['link' => $link]);


            // 标签的操作
            if($addTagIds){
                $sTagDb->whereIn('id', $addTagIds)->update($numberAdd);
                foreach($addTagIds as $_tId){
                    if(empty($_tId)){
                        continue;
                    }
                    $nTagDb->insert(['tag_id' => $_tId, 'news_id' => $news_id]);
                }
            }
            if($desTagIds){
                $sTagDb->whereIn('id', $desTagIds)->update($numberDsc);
                $nTagDb->whereIn('tag_id', $desTagIds)->where('news_id', $news_id)->delete();
            }
            // 栏目的操作
            if($addCateIds){
                $sCateDb->whereIn('id', $addCateIds)->update($numberAdd);
                foreach($addCateIds as $_cId){
                    if(empty($_cId)){
                        continue;
                    }
                    $nCateDb->insert(['cate_id' => $_cId, 'news_id' => $news_id]);
                }
            }
            if($desCateIds){
                $sCateDb->whereIn('id', $desCateIds)->update($numberDsc);
                $nCateDb->whereIn('cate_id', $desCateIds)->where('news_id', $news_id)->delete();
            }

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            //return $this->return_false($e->getMessage().':'.$e->getLine());
            return $this->return_false($e->getMessage());
        }


        // 缓存操作
        $this->deleteCacheShow($data, $info);
        $descDb->deleteCacheShow($data, $descInfo);
        $sTagDb->deleteCacheShow(['id' => $addTagIds]);
        $sTagDb->deleteCacheShow(['id' => $desTagIds]);
        $nTagDb->deleteCacheShow(['id' => $desTagIds], ['id' => $addTagIds]);
        $sCateDb->deleteCacheShow(['id' => $addCateIds]);
        $sCateDb->deleteCacheShow(['id' => $desCateIds]);
        $nCateDb->deleteCacheShow(['id' => $desCateIds], ['id' => $addCateIds]);


        return $news_id;
    }

    // 修改
    // TODO 栏目话题可以是多个的数组，也可以是单个字符串（不能是多个组合的字符串）
    public function _oneEdit($where, $data)
    {
        // 验证信息
        if(empty($is_draft)){
            $rules  = $this->fieldRule();
            $result = $this->validator($data, $rules, ['id' => '修改的用户编号']);
            if($result === false){
                return false;
            }
        }

        // 查询
        $info = $this->isCache(true)->oneFind($where);  // ->recycle()
        if(empty($info)){
            return $this->return_false('你要修改的数据不存在！！');
        }

        $info    = is_object($info) ? $info->toArray() : $info;
        $news_id = $info['id'];
        // 模型
        $descDb  = new NewsDesc();
        $nTagDb  = new NewsTag();
        $sTagDb  = new SiteTag();
        $nCateDb = new NewsCate();
        $sCateDb = new SiteCate();
        $userDb  = new User();


        // 以前的数据 与 现在的数据
        // 数据
        $articleData = $this->filterField($data);
        $descData    = $descDb->filterField($data);
        $descInfo    = [];
        if($descData){
            $descInfo = $descDb->isCache(true)->oneFind(['news_id' => $news_id]);
        }

        // 属性表改变
        $addonData = false;
        $isChange  = ((!is_null($is_original)) && ($is_original != $old_is_original)) || ((!is_null($uid)) && ($uid != $old_uid));
        if($isChange){
            $addonData = ['cate_id' => 0, 'is_original' => $is_original, 'uid' => $uid,];
        }

        // 文章话题数据
        // 以前的数据 与 现在的数据 （话题是多个）
        $cateMain      = new SiteCate();
        $topicMain     = new Topic();
        $userMain      = new User();
        $old_topic_ids = $info['topic_ids'];
        $old_cate_ids  = $info['cate_ids'];
        $topic_ids     = $data['topic_ids'] ?? [];
        $cate_ids      = $data['cate_ids'] ?? [];
        $addTopicIds   = $delTopicIds = false;
        $addCateIds    = $delCateIds = false;

        // 组合用于删除的缓存
        $data['cate_id']  = array_merge($old_cate_ids, $cate_ids);
        $data['topic_id'] = array_merge($old_topic_ids, $topic_ids);

        // 栏目的变化整理
        $addCate = [];
        $delCate = [];
        if($cate_ids && ($cate_ids != $old_cate_ids)){
            $addCateIds = array_diff($cate_ids, $old_cate_ids);  // 这些话题文章数量+1
            $delCateIds = array_diff($old_cate_ids, $cate_ids);  // 这些话题文章数量-1
            if($addCateIds){
                foreach($addCateIds as $_cateId){
                    if($_cateId){
                        $addCate[] = ['news_id' => $news_id, 'ctime' => LARAVEL_TIME, 'cate_id' => $_cateId,];
                    }
                }
            }
            if($delCateIds){
                foreach($delCateIds as $_cateId){
                    $delCate[] = ['news_id' => $news_id, 'cate_id' => $_cateId,];
                }
            }
        }
        // 话题的变化整理
        $addTopic = [];
        $delTopic = [];
        if($topic_ids && ($topic_ids != $old_topic_ids)){
            $addTopicIds = array_diff($topic_ids, $old_topic_ids);  // 这些话题文章数量+1
            $delTopicIds = array_diff($old_topic_ids, $topic_ids);  // 这些话题文章数量-1
            if($addTopicIds){
                foreach($addTopicIds as $_topicId){
                    if($_topicId){
                        $addTopic[] = ['news_id' => $news_id, 'ctime' => LARAVEL_TIME, 'topic_id' => $_topicId,];
                    }
                }
            }
            if($delTopicIds){
                foreach($delTopicIds as $_topicId){
                    $delTopic[] = ['news_id' => $news_id, 'topic_id' => $_topicId,];
                }
            }
        }

        // 日志
        $nickname = $data['nickname'];
        $content  = $nickname.'与'.date("Ymd H:i:s").'修改文章';
        $data6    = ['uid' => $data['adminId'] ?? 0, 'news_id' => $news_id, 'nickname' => $nickname, 'operate' => 'edit_article', 'content' => $content,];
        $logDb->fill($data6);


        // 文章数量
        $addNumData = ['news_no' => DB::raw("news_no+1"), 'publish_no' => DB::raw("publish_no+1"),];
        $decNumData = ['news_no' => DB::raw("news_no-1"), 'publish_no' => DB::raw("publish_no-1"),];

        // 保存数据
        DB::beginTransaction();
        try{
            /*// 如果有置顶
            if($is_top){
                // 取消其他置顶
                $result = $this->where(['is_top' => $is_top])->update(['is_top' => 0]);
            }*/

            // 主表
            if($articleData){
                $result = $this->where('id', $news_id)->update($articleData);
            }
            // 附表
            if($descData){
                $result = $descDb->where('news_id', $news_id)->update($descData);
            }

            // 属性表
            if($addonData){
                $result = $addonDb->where('news_id', $news_id)->update($addonData);;
            }
            // 添加文章话题表
            if($addTopic){
                $result = $topicDb->insert($addTopic);
            }
            // 删除文章话题表
            if($delTopicIds){
                $result = $topicDb->where('news_id', $news_id)->whereIn('topic_id', $delTopicIds)->delete();
            }
            // 话题文章数量
            if($addTopicIds){
                $result = $topicMain->whereIn('id', $addTopicIds)->update($addNumData);
            }
            if($delTopicIds){
                $result = $topicMain->whereIn('id', $delTopicIds)->update($decNumData);
            }

            // 添加文章栏目表
            if($addCate){
                $result = $cateDb->insert($addCate);
            }
            // 删除文章栏目表
            if($delCateIds){
                $result = $cateDb->where('news_id', $news_id)->whereIn('cate_id', $delCateIds)->delete();
            }
            // 栏目文章数量
            if($addCateIds){
                //$result = $cateMain->whereIn('id', $addCateIds)->update($addNumData);
            }
            if($delCateIds){
                //$result = $cateMain->whereIn('id', $delCateIds)->update($decNumData);
            }

            // 用户文章数量
            if($old_uid != $uid){
                $result = $userMain->where('id', $uid)->update($addNumData);
                $result = $userMain->where('id', $old_uid)->update($decNumData);
            }

            // 添加操作日志
            $result = $logDb->save();

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 缓存操作
        $this->deleteCacheShow($info, $data);
        $descDb->deleteCacheShow($descInfo);
        $topicMain->deleteCacheShow(['id' => $delTopicIds]);
        $topicMain->deleteCacheShow(['id' => $addTopicIds]);
        $cateMain->deleteCacheShow(['id' => $delCateIds]);
        $cateMain->deleteCacheShow(['id' => $addCateIds]);
        if($old_uid != $uid){
            $userMain->deleteCacheShow(['id' => $uid]);
            $userMain->deleteCacheShow(['id' => $old_uid]);
        }

        return $result;
    }

    // 详情
    public function oneFind($where, $order = "id DESC")
    {
        // 获取缓存
        $is_cache = $this->is_cache || $this->bang;
        $args     = compact('where', 'order');
        $info     = null;
        if($is_cache){
            $cacheName = $this->cacheKey('show', $args);
            $info      = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if($info){
                $this->checkBangShow($info, $cacheName);
            }
        }
        // 查询
        if(empty($info)){
            //  查询
            $info = $this->where($where)->orderByRaw($order)->first(); // ->recycle()
            if(empty($info)){
                return $this->return_false('news_has_no_exist');
            }

            // 查询属性
            $desc = (new NewsDesc())->where('news_id', $info->id)->first();
            $desc = $desc ? $desc->toArray() : [];
            unset($desc['id']);

            // 组合
            $info = $info->toArray();
            $info = array_merge($desc, $info);

            // 保存为缓存
            if($is_cache){
                $this->addCacheShow($info, $cacheName, $info);
            }
        }

        // 组合 标签
        $tags   = (new NewsTag())->bangField(['news_id'])->getList(['news_id' => $info['id']], 0);
        $tagIds = array_column($tags, 'tag_id');
        $tags   = (new SiteTag())->isCache(true)->getListInIds($tagIds);
        if(empty($tags)){
            $tags = [];
        }
        $info['tags']    = array_values($tags);
        $info['tag_ids'] = $tagIds;

        // 组合 栏目
        $cates   = (new NewsCate())->bangField(['news_id'])->getList(['news_id' => $info['id']], 0);
        $cateIds = array_column($cates, 'cate_id');
        $cates   = (new SiteCate())->isCache(true)->getListInIds($cateIds);
        if(empty($cates)){
            $info['cates']   = [];
            $info['en_cate'] = '';
        } else{
            $cates           = array_values($cates);
            $info['cates']   = $cates;
            $info['en_cate'] = $cates[0]['en_title'];
        }

        $info['cate_ids'] = $cateIds;
        // 编辑
        $info['user'] = [];
        if($info['uid']){
            $info['user'] = (new User())->isCache(true)->getOneById($info['uid']);
        }

        return $info;
    }

    // 获取多条数据+翻页（join）
    public function listCatePage($where = [], $page = 1, $rows = 10, $order = "apt_news.id DESC")
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'page', 'rows', 'order');
        if($is_cache){
            $cacheName = $this->cacheKey('listCatePage', $args);
            $result    = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if(($result) && (!empty($result['list']))){
                $this->checkBangList($result['list'], $cacheName);
            }
        }

        // 执行查询
        if(empty($result)){
            // 字段
            $fields   = ['news.*', 'cate.news_id', 'cate.cate_id',]; // 'cate.status'
            $all_size = $rows + 1;
            $query    = $this->from('news_cate as cate')->join('news', 'news.id', '=', 'cate.news_id');
            if(empty($where)){
                $query = $query->select($fields)->forPage($page, $rows);
                $count = $this->count();
            } else{
                if(is_array($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $query->where($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $query->where($where)->count();
                } elseif(is_string($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $query->whereRaw($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $query->whereRaw($where)->count();
                }
            }

            // 查找过滤
            $is_next = 0;
            $lists   = $query->get()->toArray();
            // 查看是否需要翻页
            if($page * $rows < $count){
                $is_next = 1;
            }

            $result = ['total' => $count, 'page' => $page, 'rows' => $rows, 'is_next' => $is_next, 'list' => $lists,];
            // 保存为缓存
            if($is_cache){
                $this->addCacheList($lists, $cacheName, $result, 'list');
            }
        }

        // 返回编辑作者
        $uids = array_unique(array_column($result['list'], 'uid'));
        if($uids){
            $userDb = new User();
            $users  = $userDb->isCache(true)->getListInIds($uids);
            foreach($result['list'] as &$item){
                $_uid = $item['uid'];
                // 整理
                $item['user'] = $users[$_uid] ?? [];
                // 头像
                if($item['user']){
                    $item['user']['head_img'] = $this->getFullUrl($item['user']['head_img']);
                }
            }
        }


        return $result;
    }

    // 获取多条数据+翻页（join）
    public function listTagPage($where = [], $page = 1, $rows = 10, $order = "apt_news.id DESC")
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'page', 'rows', 'order');
        if($is_cache){
            $cacheName = $this->cacheKey('listTagPage', $args);
            $result    = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if(($result) && (!empty($result['list']))){
                $this->checkBangList($result['list'], $cacheName);
            }
        }

        // 执行查询
        if(empty($result)){
            // 字段
            $fields   = ['news.*', 'tag.news_id', 'tag.tag_id',]; // 'cate.status'
            $all_size = $rows + 1;
            $query    = $this->from('news_tag as tag')->join('news', 'news.id', '=', 'tag.news_id');
            if(empty($where)){
                $query = $query->select($fields)->forPage($page, $rows);
                $count = $this->count();
            } else{
                if(is_array($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $query->where($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $query->where($where)->count();
                } elseif(is_string($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $query->whereRaw($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $query->whereRaw($where)->count();
                }
            }

            // 查找过滤
            $is_next = 0;
            $lists   = $query->get()->toArray();
            // 查看是否需要翻页
            if($page * $rows < $count){
                $is_next = 1;
            }

            $result = ['total' => $count, 'page' => $page, 'rows' => $rows, 'is_next' => $is_next, 'list' => $lists,];
            // 保存为缓存
            if($is_cache){
                $this->addCacheList($lists, $cacheName, $result, 'list');
            }
        }

        // 返回编辑作者
        $uids = array_unique(array_column($result['list'], 'uid'));
        if($uids){
            $userDb = new User();
            $users  = $userDb->isCache(true)->getListInIds($uids);
            foreach($result['list'] as &$item){
                $_uid = $item['uid'];
                // 整理
                $item['user'] = $users[$_uid] ?? [];
                // 头像
                if($item['user']){
                    $item['user']['head_img'] = $this->getFullUrl($item['user']['head_img']);
                }
            }
        }


        return $result;
    }

    // 获取多条数据+翻页
    public function listPage($where = [], $page = 1, $rows = 10, $order = "id DESC")
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'page', 'rows', 'order');
        if($is_cache){
            $cacheName = $this->cacheKey('lists', $args);
            $result    = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if(($result) && (!empty($result['list']))){
                $this->checkBangList($result['list'], $cacheName);
            }
        }

        // 执行查询
        if(empty($result)){
            $fields    = $this->inFields;
            $outFields = $this->outFields;
            if(empty($fields)){
                $fields = $this->getTableField(true);
            }
            if(is_string($fields)){
                $fields = explode(",", $fields);
            }
            if($outFields){
                if(is_string($outFields)){
                    $outFields = explode(",", $outFields);
                }
                $fields = array_diff($fields, $outFields);
            }

            $all_size = $rows + 1;
            if(empty($where)){
                $query = $this->select($fields)->forPage($page, $rows);
                $count = $this->count();
            } else{
                if(is_array($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $this->where($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $this->where($where)->count();
                } elseif(is_string($where)){
                    // 查询  ->recycle()  ->orderby($order)
                    $query = $this->whereRaw($where)->select($fields)->forPage($page, $rows)->orderByRaw($order);
                    $count = $this->whereRaw($where)->count();
                }
            }

            // 查找过滤
            $is_next = 0;
            $lists   = $query->get()->toArray();
            // 查看是否需要翻页
            if($page * $rows < $count){
                $is_next = 1;
            }

            $result = ['total' => $count, 'page' => $page, 'rows' => $rows, 'is_next' => $is_next, 'list' => $lists,];
            // 保存为缓存
            if($is_cache){
                $this->addCacheList($lists, $cacheName, $result, 'list');
            }
        }


        // 过滤json
        $jsonField = isset($this->jsonField) ?: '';
        if(!empty($jsonField)){
            $jsonField = is_string($jsonField) ? explode(',', $jsonField) : $jsonField;
            foreach($result['list'] as &$_list){
                foreach($jsonField as $_field){
                    $_list->$_field = json_decode($_list->$_field, 1);
                }
            }
        }

        // 返回编辑作者
        $uids = array_unique(array_column($result['list'], 'uid'));
        if($uids){
            $userDb = new User();
            $users  = $userDb->isCache(true)->getListInIds($uids);
            foreach($result['list'] as &$item){
                $_uid = $item['uid'];
                // 整理
                $item['user'] = $users[$_uid] ?? [];
                // 头像
                if($item['user']){
                    $item['user']['head_img'] = $this->getFullUrl($item['user']['head_img']);
                }
            }
        }

        return $result;
    }

    // 获取多条数据 不翻页（join）
    public function getCateList($where = [], $number = 10, $order = "apt_news.id DESC", $offset = 0)
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'number', 'order', 'offset');
        if($is_cache){
            $cacheName = $this->cacheKey('cate_lists', $args);
            $lists     = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if(!empty($lists)){
                $this->checkBangList($lists, $cacheName);
            }
        }

        // 查询数据
        if(empty($lists)){
            // 查询
            $query = $this->from('news_cate as cate')->join('news', 'news.id', '=', 'cate.news_id')->orderByRaw($order);
            if($number){
                $lists = $query->where($where)->offset($offset)->limit($number)->get()->toArray();
            } else{
                $lists = $query->where($where)->get()->toArray();
            }

            // 保存为缓存
            if($is_cache){
                $this->addCacheList($lists, $cacheName, $lists, 'list');
            }
        }

        // 过滤json
        $jsonField = isset($this->jsonField) ?: '';
        if(!empty($jsonField)){
            $jsonField = is_string($jsonField) ? explode(',', $jsonField) : $jsonField;
            foreach($lists as &$_list){
                foreach($jsonField as $_field){
                    $_list->$_field = json_decode($_list->$_field, 1);
                }
            }
        }

        return $lists;
    }

    // 获取多条数据 不翻页（join）
    public function getTagList($where = [], $number = 10, $order = "apt_news.id DESC", $offset = 0)
    {
        // 获取缓存
        $bang     = $this->bang;
        $is_cache = $this->is_cache || $bang;
        $args     = compact('where', 'number', 'order', 'offset');
        if($is_cache){
            $cacheName = $this->cacheKey('tag_lists', $args);
            $lists     = $this->cacheClass()->getCache($cacheName);
            // 检查是否已经绑定
            if(!empty($lists)){
                $this->checkBangList($lists, $cacheName);
            }
        }

        // 查询数据
        if(empty($lists)){
            // 查询
            $query = $this->from('news_tag as tag')->join('news', 'news.id', '=', 'tag.news_id')->orderByRaw($order);
            if($number){
                $lists = $query->where($where)->offset($offset)->limit($number)->get()->toArray();
            } else{
                $lists = $query->where($where)->get()->toArray();
            }

            // 保存为缓存
            if($is_cache){
                $this->addCacheList($lists, $cacheName, $lists, 'list');
            }
        }

        // 过滤json
        $jsonField = isset($this->jsonField) ?: '';
        if(!empty($jsonField)){
            $jsonField = is_string($jsonField) ? explode(',', $jsonField) : $jsonField;
            foreach($lists as &$_list){
                foreach($jsonField as $_field){
                    $_list->$_field = json_decode($_list->$_field, 1);
                }
            }
        }

        return $lists;
    }

    // 删除文章
    public function softDelete($where)
    {
        $lists = $this->isCache(true)->getList($where);  //->recycle()
        if(empty($lists)){
            return $this->return_false('你要删除的数据不存在！！');
        }


        // 模型
        $descDb  = new NewsDesc();
        $nTagDb  = new NewsTag();
        $sTagDb  = new SiteTag();
        $nCateDb = new NewsCate();
        $sCateDb = new SiteCate();
        $userDb  = new User();


        $_ids   = array_column($lists, 'id');
        $tagNum = $cateNum = [];
        // 查找有关的标签 + 栏目
        $newsTags  = $nTagDb->whereIn('news_id', $_ids)->get()->toArray();
        $newsCates = $nCateDb->whereIn('news_id', $_ids)->get()->toArray();
        foreach($newsTags as $item){
            $_tagId = $item['tag_id'];
            // 重新整理
            $tagNum[$_tagId] = ($tagNum[$_tagId] ?? 0) + 1;
        }
        foreach($newsCates as $item){
            $_cateId = $item['cate_id'];
            // 重新整理
            $cateNum[$_cateId] = ($cateNum[$_cateId] ?? 0) + 1;
        }


        DB::beginTransaction();
        try{
            // 删除文章附件，属性，日志，评论
            $this->whereIn('id', $_ids)->update(['verify' => -1]);

            // 减少标签
            if($tagNum){
                foreach($tagNum as $_tId => $_num){
                    $sTagDb->where('id', $_tId)->update(['number' => DB::raw("number-".$_num)]);
                }
            }
            // 减少栏目
            if($cateNum){
                foreach($cateNum as $_cId => $_num){
                    $sCateDb->where('id', $_cId)->update(['number' => DB::raw("number-".$_num)]);
                }
            }

            // 刪除栏目
            (new NewsCate())->whereIn('news_id', $_ids)->update(['status' => -1]);

            // 删除标签
            (new NewsTag())->whereIn('news_id', $_ids)->delete();

            DB::commit();
        } catch(\Exception $e){
            DB::rollBack();

            return $this->return_false($e->getMessage());
        }

        // 缓存操作
        $this->deleteCacheList($lists);
        $this->deleteCacheShow(['id' => $_ids, 'verify' => -1]);
        $sCateDb->deleteCacheShow(['id' => array_keys($cateNum)]);
        $sTagDb->deleteCacheShow(['id' => array_keys($tagNum)]);

        return true;
    }

    // 浏览记录
    public function addView($article_id)
    {
        //更新访问信息
        $number  = mt_rand(5, 10);
        $updata  = ["read_no" => DB::raw("read_no+1"), "virtual_no" => DB::raw("virtual_no+".$number),];
        $upCache = ["read_no" => "+1", "virtual_no" => "+$number",];

        // 增加访问量
        $where = ["id" => $article_id];  // 条件
        $this->where($where)->update($updata);

        // 缓存操作
        $this->deleteCacheShow($where);
        // 文章详情 重新缓存
        $this->reSaveCache($article_id, $upCache);

        return true;
    }

    // 文件地址
    protected function getFullUrl($url)
    {
        if(!$url) return '';
        if(substr($url, 0, 4) != 'http'){
            $domain = Config::get('site.cdnHost');
            $domain = substr($domain, -1) == '/' ? substr($domain, 0, -1) : $domain;
            $url    = $domain.$url;
        }

        return $url;
    }

    // 关键词 与 标签
    protected function keywordToTag($keywordsString, $field = 'en_keyword')
    {
        if(empty($keywordsString)){
            return [];
        }

        // 1、查找关键词，匹配标签
        // 2、如果没有的标签，先添加保存到数据库中
        $tagIds   = [];
        $keywords = explode(',', $keywordsString);
        foreach($keywords as $_keyword){
            $_has = (new SiteTag())->where($field, $_keyword)->where('status', 1)->first();
            if(empty($_has)){
                // 添加
                // 进行翻译 中文 繁体
                $cn_title = $this->translate($_keyword, 'cn');
                $tc_title = $this->translate($_keyword, 'tc');
                $row      = [
                    'id'       => '编号',
                    'rank'     => '排序',
                    'en_title' => $_keyword,
                    'cn_title' => $cn_title,
                    'tc_title' => $tc_title,
                    'number'   => '0',
                    'status'   => 1,
                    //'ctime'    => '创建时间',
                    //'mtime'    => '修改时间',
                ];

                $tagId = (new SiteTag())->insertGetId($row);
            } else{
                $tagId = $_has->id;
            }

            $tagIds[] = $tagId;
        }

        return $tagIds;
    }

    // 执行翻译
    protected function translate($text, $lang)
    {
        if(empty($text)){
            return '';
        }

        $translate = new Translate();
        $result    = $translate->translateTo($text, $lang);

        return $result['text'] ?? '';
    }

    // 定义验证操作
    public function rules()
    {

        $add = [
            //'uid' => 'required',
        ];

        $edit = [
        ];

        $info = [
        ];


        $rule = [
            // 详情
            //'content'     => 'sometimes|required',

            //'id'             => 'required',
            //'en_title'       => 'required',
            //'cn_title'       => 'required',
            //'tc_title'       => 'required',
            //'en_description' => 'required',
            //'cn_description' => 'required',
            //'tc_description' => 'required',
            //'author'         => 'required',
            'pic'        => 'sometimes|required',
            'images'     => 'required',
            'read_no'    => 'numeric',
            'virtual_no' => 'numeric',
            'comment_no' => 'numeric',
            'praise_no'  => 'numeric',
            'collect_no' => 'numeric',
            'verify'     => ['in:0,1'],
            //'ip'             => 'required',
            //'ip_address'     => 'required',
            'is_top'     => ['in:0,1'],
            'is_header'  => ['in:0,1'],
            'is_major'   => ['in:0,1'],
            'is_draft'   => ['in:0,1'],
            'is_email'   => ['in:0,1'],
            //'from_site'      => 'required',
            //'from_url'       => 'required',
            //'header_time'    => 'required',
            //'email_time'     => 'required',
            //'major_time'     => 'required',
            //'top_time'       => 'required',
        ];


        $msg = [
            'id'             => '自编号',
            'uid'            => '用户id',
            'en_title'       => '标题（英文）',
            'cn_title'       => '标题（中文）',
            'tc_title'       => '标题（繁体）',
            'en_description' => '描述(英文)',
            'cn_description' => '描述(中文)',
            'tc_description' => '描述(繁体)',
            'author'         => '作家',
            'pic'            => '图片',
            'images'         => '图片集合',
            'read_no'        => '浏览数',
            'virtual_no'     => '虚拟浏览数',
            'comment_no'     => '评论数',
            'praise_no'      => '点赞数',
            'collect_no'     => '收藏数',
            'verify'         => '是否审核（1-是，-1删除）',
            'ip'             => 'ip地址',
            'ip_address'     => 'ip的实际地址',
            'is_top'         => '是否突发（1-是）',
            'is_header'      => '是否头条',
            'is_major'       => '是否标红',
            'is_draft'       => '是否草稿 1-是',
            'is_email'       => '是否邮件转发',
            'from_site'      => '',
            'from_url'       => '采集的文章来源',
            'header_time'    => '设置头条时间',
            'email_time'     => '邮件时间',
            'major_time'     => '指定时间',
            'top_time'       => '置顶时间',
            'ctime'          => '创建时间',
            'mtime'          => '修改时间',
        ];

        return ['rule' => $rule, 'msg' => $msg, 'add' => $add];
    }

}
